QDA Package Format
Archived from http://www.cinnamonpirate.com/docs/neicpak on 2006/2/7
Grudgingly copied and pasted from his browser by D

The QDA package format is used by buster in all his latest Windows games, like Guardian of Paradise and Akuji the Demon.

Like Fastfile, it condenses a directory full of images down to one package to be used as a mini-filesystem by the game.

The format begins with a 0×100 byte header, then begins a pattern where it repeats 268 byte chunks. Its maximum storable filename is 255 bytes. All values are stored in little endian ordering:

Null [4 bytes, long]
ID Tag: 'QDA0' [4 bytes, string]
File count [4 bytes, long]
(pad up to 0x100)
(file loop)
  File offset [4 bytes, long]
  File size [4 bytes, long]
  Repeat file size [4 bytes, long (unconfirmed)
  File name [256 bytes, string]
(end loop)

Despite not being certain about the repeated file size, I was able to successfully rebuild QDA packages from scratch and have them work in buster’s game by copying the file size to both offsets.

A proof of concept extractor is shown below:

$fd = fopen('bmp.qda', 'rb');
fseek($fd, 0x4, SEEK_SET);
if(fread($fd, 4)!="QDA0") die;
list($junk, $count) = unpack('l*', fread($fd, 4));
$offset = array();
$filesize = array();
$unknown = array();
$name = array();
for($i=0; $i< $count; $i++) {
  list($junk, $offset[$i]) = unpack('l*', fread($fd, 4));
  list($junk, $filesize[$i]) = unpack('l*', fread($fd, 4));
  list($junk, $unknown[$i]) = unpack('l*', fread($fd, 4));
  $filename[$i] = rtrim(fread($fd, 256));
}
for($i=0; $i<$count; $i++) {
  $fo = fopen($filename[$i], 'w');
  fseek($fd, $offset[$i], SEEK_SET);
  fputs($fo, fread($fd, $filesize[$i]));
  fclose($fo);
}
fclose($fd);